package demo19;

/*
    给你一个链表，删除链表的倒数第 n 个结点，并且返回链表的头结点。

    进阶：你能尝试使用一趟扫描实现吗？
 */
public class Test {
    public static void main(String[] args) {

        ListNode ln = new ListNode(1);
        ListNode start = ln;
        for (int i = 2; i < 31; i++) {
            ln.next = new ListNode(i);
            ln = ln.next;
        }
        ListNode result = removeNthFromEnd(start,20);
        while(result.next != null){
            System.out.print(" "+result.val);
            result = result.next;
        }
        System.out.print(" "+result.val);

    }

//    //传统思路
//    public static ListNode removeNthFromEnd(ListNode head, int n) {
//        //先遍历一遍，看看这个链表长度是多少
//        int length = 1;
//        ListNode ln = head;
//        ListNode result = head;
//        while(head.next != null){
//            length++;
//            head = head.next;
//        }
//        //如果链表只有一个节点，直接剔除返回即可
//        if(length == 1){
//            return null;
//        }
//        //求出顺序读取的话，删除节点的位置
//        int way = length-n;
//        System.out.println(way);
//        if(way <= 0){
//            //如果要删除的位置指向开头或者超过了链表长度，去掉链表第一个即可
//            result = ln.next;
//            return result;
//        }
//        //推进链表
//        for (int i = 0; i < way-1; i++) {
//            ln = ln.next;
//        }
//        //将要删除的节点的前一节点，指向下下个节点
//        ln.next = ln.next.next;
//        return result;
//    }

    //优化思路
    public static ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode ln = head;//这个链表是用来返回起点的
        //定义起点链表
        ListNode start = head;
        //定义终点链表
        ListNode end = head;
        for (int i = 0; i < n; i++) {
            //让end走n-1步，使start与end的距离为n
            if(end.next == null){
                //还没走到距离为n-1，就已经到尽头了，那么只是剔除开头链表即可
                return ln.next;
            }
            end = end.next;
        }
        //成功让start与end的距离为n,只要等到end走到尽头，就可以让start指向下下个位置即可剔除对应节点
        while(end.next != null){
            end = end.next;
            start = start.next;
        }
        //剔除掉start的下一个节点
        start.next = start.next.next;
        return ln;
    }

}



class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}